/**
 * 
 */
package com.everis.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

/**
 * @author vmorepal
 *
 */
public class FileUtil {
	
	/***
	 * Metodo que genera un archivo en la ruta enviada como parametro
	 * 
	 * @param archivo_texto contenido del archivo
	 * @param ruta ruta donde se generara el archivo
	 * @return true si es exitoso, false si existe error
	 */
	public static boolean grabarArchivo(String archivo_texto, String ruta) {
		boolean se_grabo = false;
		try {
			File archivo = new File(ruta);

			BufferedWriter archivo_salida = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(archivo), "UTF8"));
			archivo_salida.write(archivo_texto);
			archivo_salida.close();
			se_grabo = true;
		}
		catch (IOException e) {
			se_grabo = false;
		}
		catch (Exception e) {
			se_grabo = false;
			e.printStackTrace();
		}
		return se_grabo;
	}
	
	/***
	 * Metodo que devuelve un arreglo de byte de un archivo
	 * @param archivo archivo seleccionado
	 * @return
	 * @throws IOException 
	 */
	public static byte[] obtenerByteArrayDesdeArchivo(File archivo) throws IOException {
		byte[] arreglo_bytes = null;

		// create FileInputStream object
		FileInputStream fin = null;
		try {
			fin = new FileInputStream(archivo);
			arreglo_bytes = new byte[(int) archivo.length()];
			fin.read(arreglo_bytes);
			fin.close();
		}
		catch (FileNotFoundException e) {
			throw new FileNotFoundException("No se encontro archivo " + e);
		}
		catch (IOException e) {
			throw new IOException(e);
		}
		return arreglo_bytes;
	}
	
	/***
	 * Metodo que sirve para copiar un archivo de una ruta a otra
	 * @param archivo_destino  archivo destino
	 * @param fuente  archivo origen que se desea copiar
	 * @return true si es exitoso, false si existe error
	 */
	public static boolean copiarArchivo(File archivo_destino, File fuente) {
		boolean exito = true;
		try {
			FileInputStream inStream = new FileInputStream(fuente);
			FileOutputStream outStream = new FileOutputStream(archivo_destino);

			int len;
			byte[] buf = new byte[2048];

			while ((len = inStream.read(buf)) != -1) {
				outStream.write(buf, 0, len);
			}
			outStream.close();
			inStream.close();
		}
		catch (Exception e) {
			e.printStackTrace();
			exito = false;
		}

		return exito;
	}
	
	/***
	 * Metodo para crear un directorio en una ruta especifica
	 * @param urlDirectorio ruta del directorio a crear
	 * @return true si es exitoso, false si existe error
	 * @throws Exception 
	 */
	public static boolean crearDirectorio(String urlDirectorio) throws Exception {
		boolean creado = false;
		File nuevo_directorio = new File(urlDirectorio);
		if (nuevo_directorio.exists()) {
			creado = true;
		}
		else {
			try {
				creado = nuevo_directorio.mkdir();
			}
			catch (Exception e) {
				throw new Exception(e);
			}
		}
		return creado;
	}
	
	/***
	 * Metodo que retorna el tamanio de un archivo en KB
	 * @param ruta_local ruta del archivo
	 * @return size del archivo en KB
	 * @throws Exception 
	 */
	public static double obtenerTamanioArchivoLocalEnKB(String ruta_local) throws Exception {
		double tamanho = -1;
		try {
			File archivo = new File(ruta_local);
			tamanho = NumberUtil.redondeaDouble(archivo.length() / 1024.0, 2);
		}
		catch (Exception e) {
			tamanho = -1;
			throw new Exception(e);
		}
		return tamanho;
	}
	
	/***
	 * Metodo que indica si 2 archivos son iguales
	 * @param file1 archivo1
	 * @param file2 archivo2
	 * @return true si son iguales los archivos, caso contrario retorna false
	 * @throws IOException 
	 */
	public static boolean sonArchivosIdenticos(File file1, File file2) throws IOException {
		boolean result = true;

		if (file1.length() != file2.length()) {
			result = false;
		}
		else {
			try {
				FileInputStream in1 = new FileInputStream(file1);
				FileInputStream in2 = new FileInputStream(file2);

				int buf = -1;

				while ((buf = in1.read()) > -1 && result == true) {
					result = buf == in2.read();
				}
				
				in2.close();
				in1.close();
			}
			catch (IOException e) {
				result = false;
				throw new IOException(e);
			}
		}

		return result;
	}
	
	/***
	 * Metodo que guarda arreglo de bytes en un archivo
	 * @param arreglo_bytes  arreglo de bytes a guardar
	 * @param ruta_archivo  ruta del archivo de salida
	 * @return true si es exitoso, false si existe error
	 * @throws IOException 
	 */
	public static boolean guardarBytesEnArchivo(byte[] arreglo_bytes, String ruta_archivo) throws IOException {
		boolean exito = false;
		try {
			FileOutputStream fos = new FileOutputStream(ruta_archivo);

			fos.write(arreglo_bytes);
			fos.close();
			exito = true;
		}
		catch (FileNotFoundException ex) {
			throw new FileNotFoundException();
		}
		catch (IOException ioe) {
			throw new IOException(ioe);
		}
		return exito;
	}
	
	/***
	 * Metodo que borra un directorio
	 * @param urlDirectorio  ruta del directorio a eliminar
	 * @return true si se elimina el directorio, caso contrario false
	 * @throws Exception 
	 */
	public static boolean borrarDirectorio(String urlDirectorio) throws Exception {
		boolean borrado = false;
		File directorioBorrar = new File(urlDirectorio);
        if( !directorioBorrar. exists() ) {
        	borrado=true;
        }else{
        	try {
        		File[] files = directorioBorrar. listFiles();
                for(int i=0; i<files. length; i++) {
                             files[i]. delete();
                }
                borrado=directorioBorrar.delete();
			}
			catch (Exception e) {
				throw new Exception(e);
			}
        }
		return borrado;
	}
	
	/***
	 * Metodo que convierte un InputStream en un archivo de texto
	 * @param inputStream
	 * @return un archivo de texto temporal 
	 * @throws IOException 
	 */
	public static File convertInputStreamToFileText(InputStream inputStream) throws IOException{		
		OutputStream outputStream = null;
		File returnFile=null;
		try {	 
			returnFile=File.createTempFile("tmp", ".txt");  
			outputStream = new FileOutputStream(returnFile);
	 
			int read = 0;
			byte[] bytes = new byte[1024];
	 
			while ((read = inputStream.read(bytes)) != -1) {
				outputStream.write(bytes, 0, read);
			}			
		} catch (IOException e) {
			throw new IOException(e);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					throw new IOException(e);
				}
			}
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					throw new IOException(e);
				}
	 
			}
		}
		return returnFile;
	}
	
	/***
	 * Metodo que descomprime un archivo en una ruta especifica
	 * @param file  archivo comprimido
	 * @param rutaDestino  ruta destino donde se descomprimira el archivo
	 * @return true si es exitoso, false si existe error
	 * @throws IOException 
	 * @throws InterruptedException 
	 */
	public static boolean descomprimirArchivo(File file, String rutaDestino) throws IOException, InterruptedException{
		boolean exito = false;
		try {
			String compositeCommand="unzip -o "+file.getAbsolutePath()+" -d "+rutaDestino;
			Process process = Runtime.getRuntime().exec(compositeCommand,null);
			process.waitFor();
			exito = true;
		} catch (IOException e) {
			throw new IOException(e);
		} catch (InterruptedException ex) {
			throw new InterruptedException();
		}
		return exito;
	}
}
